﻿using BasicsClassLibrary.Tool.Configure;
using Dapper;
using DotNetCore.CAP;
using DtmCommon;
using Microsoft.Extensions.Configuration;
using MySqlConnector;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MQCommon
{
    public class DapperHelper
    {
        static DapperHelper()
        {
            //ReloadOnChange = true 当appsettings.json被修改时重新加载   
            var appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? String.Empty;
            var cfgPath = Path.Combine(appDir, "appsettings.json");

            IConfigurationRoot? config = new ConfigurationBuilder()
                .AddJsonFile(cfgPath)
                .Build();
            _dbConnection = new MySqlConnection();
            _dbConnection.ConnectionString = config.GetSection("Database:ConnectionString").Value;
           

        }
        public string connectstr  ()
        {
             var appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? String.Empty;
            var cfgPath = Path.Combine(appDir, "appsettings.json");

            IConfigurationRoot? config = new ConfigurationBuilder()
                .AddJsonFile(cfgPath)
                .Build();
            return config.GetSection("Database:ConnectionString").Value;
        }
        private static readonly DbConnection _dbConnection;

        #region Query
        public async Task<T> QueryFirstOrDefaultAsync<T>(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, CommandType? commandType = null)
        {
            return await _dbConnection.QueryFirstOrDefaultAsync<T>(sql, param, transaction, commandTimeout, commandType);
        }
        public T QueryFirstOrDefault<T>(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, CommandType? commandType = null)
        {
            return _dbConnection.QueryFirstOrDefault<T>(sql, param, transaction, commandTimeout, commandType);
        }
        public async Task<List<T>> QueryAsync<T>(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, CommandType? commandType = null)
        {
            return (await _dbConnection.QueryAsync<T>(sql, param, transaction, commandTimeout, commandType)).ToList();
        }
        public List<T> Query<T>(string sql, object param = null, IDbTransaction transaction = null,
            bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _dbConnection.Query<T>(sql, param, transaction, buffered, commandTimeout, commandType).ToList();
        }
        #endregion

        #region Excute
        public async Task DTMTransactionAsync(Action action, BranchBarrier branchBarrier)
        {
            using (var connection = new MySqlConnection(_dbConnection.ConnectionString))
            {
                await branchBarrier.Call(connection, async (tx) =>
                {
                    action.Invoke();
                    await Task.CompletedTask;
                });
            }

                

        }
        public void BeginTransaction(Action action, ICapPublisher _capBus)
        {
            using (var transaction = _dbConnection.BeginTransaction(_capBus, autoCommit: false))
            {
                try
                {

                    action.Invoke();
                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }
        public Task<int> ExecuteAsync(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, CommandType? commandType = null)
        {
            return _dbConnection.ExecuteAsync(sql, param, transaction, commandTimeout, commandType);
        }
        public int Execute(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, CommandType? commandType = null)
        {
            return _dbConnection.Execute(sql, param, transaction, commandTimeout, commandType);
        }


        #endregion
    }
}
